<?php

/**
 * Raise class
 * loads all the required components
 *
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package Raise.Core
 * @since 1.2
 */
class Raise {

    /**
     * A registry of all included classes
     * @var array
     * @staticvar
     */
    private static $classRegistry = array();

    /**
     * Defines the phpRaise framework version
     * @var string
     * @staticvar
     */
    private static $frameworkVersion = '1.2b';

    /**
     * phpRaise root directory
     * @var string
     * @staticvar
     */
    private static $root;

    /**
     * Get the phpRaise framework version
     * @return RaiseVersion The RaiseVersion representation of phpRaise framework version
     * @static
     */
    public static function version(){
        return new RaiseVersion(self::$frameworkVersion);
    }

    /**
     * Load a particular class or multiple classes
     * @param string $package The class(es) to load using their physical package i.e. core.RaiseObject -> core/RaiseObject.php. If wildcards are used, multiple classes may be included.
     * @static
     */
    public static function load($package){
        $s = str_replace('.', DIRECTORY_SEPARATOR, $package);
        $file = self::$root . $s . '.php';
        foreach(glob($file, GLOB_NOSORT) as $f){
            $t = explode(DIRECTORY_SEPARATOR, substr($f, 0, strlen($f)-4));
            $machine = end($t);
            if(array_key_exists($machine, self::$classRegistry)){
                self::$classRegistry[$machine]++;
            }else{
                include_once($f);
                if(class_exists($machine) && in_array('IRaiseInitializable', class_implements($machine))){
                    call_user_func($machine.'::initialize');
                }
                self::$classRegistry[$machine] = 1;
            }
        }
    }

    /**
     * Load all exception classes
     * @static
     */
    public static function loadExceptions(){
        self::load('core.RaiseException');
        self::load('exception.Raise*Exception');
    }

    /**
     * Fetch all classes that are loaded in the framework
     * @return array
     * @static
     */
    public static function loadedClasses(){
        return array_keys(self::$classRegistry);
    }

    /**
     * Get the number of times a particular class has been loaded via Raise's loader
     * @param string|object $class Name of the class or object
     * @return integer
     * @static
     */
    public static function classLoadCount($class){
        if(is_object($class)){
            $class = get_class($class);
        }
        if(array_key_exists($class, self::$classRegistry)){
            return self::$classRegistry[$class];
        }else{
            return 0;
        }
    }

    /**
     * Discover the root directory of the framework
     * @static
     */
    public static function loadRoot(){
        if(!self::$root){
            self::$root = pathinfo(__FILE__, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR;
        }
    }

}

/**
 * Load all components
 */
Raise::loadRoot();
Raise::loadExceptions();
Raise::load('core.RaiseApplication');
Raise::load('core.RaiseConsoleApplication');